home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / inet / gethstnmad.c next >
C/C++ Source or Header  |  1993-05-19  |  12KB  |  507 lines

  1. /*
  2.  * ++Copyright++ 1985, 1988
  3.  * -
  4.  * Copyright (c) 1985, 1988 Regents of the University of California.
  5.  * All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)gethostnamadr.c    6.47 (Berkeley) 6/18/92";
  58. static char rcsid[] = "$Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61. #include <sys/param.h>
  62. #include <sys/socket.h>
  63. #include <netinet/in.h>
  64. #include <arpa/inet.h>
  65. #include <arpa/nameser.h>
  66. #include <netdb.h>
  67. #include <resolv.h>
  68. #include <stdio.h>
  69. #include <ctype.h>
  70. #include <errno.h>
  71. #include "../conf/portability.h"
  72.  
  73. #define    MAXALIASES    35
  74. #define    MAXADDRS    35
  75.  
  76. static char *h_addr_ptrs[MAXADDRS + 1];
  77.  
  78. static struct hostent host;
  79. static char *host_aliases[MAXALIASES];
  80. static char hostbuf[BUFSIZ+1];
  81. static struct in_addr host_addr;
  82. static FILE *hostf = NULL;
  83. static char hostaddr[MAXADDRS];
  84. static char *host_addrs[2];
  85. static int stayopen = 0;
  86. char *strpbrk();
  87.  
  88. #if PACKETSZ > 1024
  89. #define    MAXPACKET    PACKETSZ
  90. #else
  91. #define    MAXPACKET    1024
  92. #endif
  93.  
  94. typedef union {
  95.     HEADER hdr;
  96.     u_char buf[MAXPACKET];
  97. } querybuf;
  98.  
  99. typedef union {
  100.     int32_t al;
  101.     char ac;
  102. } align;
  103.  
  104. extern int h_errno;
  105.  
  106. static struct hostent *
  107. getanswer(answer, anslen, iquery)
  108.     querybuf *answer;
  109.     int anslen;
  110.     int iquery;
  111. {
  112.     register HEADER *hp;
  113.     register u_char *cp;
  114.     register int n;
  115.     u_char *eom;
  116.     char *bp, **ap;
  117.     int type, class, buflen, ancount, qdcount;
  118.     int haveanswer, getclass = C_ANY;
  119.     char **hap;
  120.  
  121.     eom = answer->buf + anslen;
  122.     /*
  123.      * find first satisfactory answer
  124.      */
  125.     hp = &answer->hdr;
  126.     ancount = ntohs(hp->ancount);
  127.     qdcount = ntohs(hp->qdcount);
  128.     bp = hostbuf;
  129.     buflen = sizeof(hostbuf);
  130.     cp = answer->buf + sizeof(HEADER);
  131.     if (qdcount) {
  132.         if (iquery) {
  133.             if ((n = dn_expand((u_char *)answer->buf,
  134.                 (u_char *)eom, (u_char *)cp, (u_char *)bp,
  135.                 buflen)) < 0) {
  136.                 h_errno = NO_RECOVERY;
  137.                 return ((struct hostent *) NULL);
  138.             }
  139.             cp += n + QFIXEDSZ;
  140.             host.h_name = bp;
  141.             n = strlen(bp) + 1;
  142.             bp += n;
  143.             buflen -= n;
  144.         } else
  145.             cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  146.         while (--qdcount > 0)
  147.             cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  148.     } else if (iquery) {
  149.         if (hp->aa)
  150.             h_errno = HOST_NOT_FOUND;
  151.         else
  152.             h_errno = TRY_AGAIN;
  153.         return ((struct hostent *) NULL);
  154.     }
  155.     ap = host_aliases;
  156.     *ap = NULL;
  157.     host.h_aliases = host_aliases;
  158.     hap = h_addr_ptrs;
  159.     *hap = NULL;
  160. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  161.     host.h_addr_list = h_addr_ptrs;
  162. #endif
  163.     haveanswer = 0;
  164.     while (--ancount >= 0 && cp < eom) {
  165.         if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom,
  166.             (u_char *)cp, (u_char *)bp, buflen)) < 0)
  167.             break;
  168.         cp += n;
  169.         type = _getshort(cp);
  170.          cp += sizeof(u_short);
  171.         class = _getshort(cp);
  172.          cp += sizeof(u_short) + sizeof(u_int32_t);
  173.         n = _getshort(cp);
  174.         cp += sizeof(u_short);
  175.         if (type == T_CNAME) {
  176.             cp += n;
  177.             if (ap >= &host_aliases[MAXALIASES-1])
  178.                 continue;
  179.             *ap++ = bp;
  180.             n = strlen(bp) + 1;
  181.             bp += n;
  182.             buflen -= n;
  183.             continue;
  184.         }
  185.         if (iquery && type == T_PTR) {
  186.             if ((n = dn_expand((u_char *)answer->buf,
  187.                 (u_char *)eom, (u_char *)cp, (u_char *)bp,
  188.                 buflen)) < 0) {
  189.                 cp += n;
  190.                 continue;
  191.             }
  192.             cp += n;
  193.             host.h_name = bp;
  194.             return(&host);
  195.         }
  196.         if (iquery || type != T_A)  {
  197. #ifdef DEBUG
  198.             if (_res.options & RES_DEBUG)
  199.                 printf("unexpected answer type %d, size %d\n",
  200.                     type, n);
  201. #endif
  202.             cp += n;
  203.             continue;
  204.         }
  205.         if (haveanswer) {
  206.             if (n != host.h_length) {
  207.                 cp += n;
  208.                 continue;
  209.             }
  210.             if (class != getclass) {
  211.                 cp += n;
  212.                 continue;
  213.             }
  214.         } else {
  215.             host.h_length = n;
  216.             getclass = class;
  217.             host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  218.             if (!iquery) {
  219.                 host.h_name = bp;
  220.                 bp += strlen(bp) + 1;
  221.             }
  222.         }
  223.  
  224.         bp += sizeof(align) - ((u_int32_t)bp % sizeof(align));
  225.  
  226.         if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
  227. #ifdef DEBUG
  228.             if (_res.options & RES_DEBUG)
  229.                 printf("size (%d) too big\n", n);
  230. #endif
  231.             break;
  232.         }
  233.         bcopy(cp, *hap++ = bp, n);
  234.         bp +=n;
  235.         cp += n;
  236.         haveanswer++;
  237.     }
  238.     if (haveanswer) {
  239.         *ap = NULL;
  240. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  241.         *hap = NULL;
  242. #else
  243.         host.h_addr = h_addr_ptrs[0];
  244. #endif
  245.         return (&host);
  246.     } else {
  247.         h_errno = TRY_AGAIN;
  248.         return ((struct hostent *) NULL);
  249.     }
  250. }
  251.  
  252. struct hostent *
  253. gethostbyname(name)
  254.     const char *name;
  255. {
  256.     querybuf buf;
  257.     register const char *cp;
  258.     int n;
  259.     extern struct hostent *_gethtbyname();
  260.  
  261.     /*
  262.      * disallow names consisting only of digits/dots, unless
  263.      * they end in a dot.
  264.      */
  265.     if (isdigit(name[0]))
  266.         for (cp = name;; ++cp) {
  267.             if (!*cp) {
  268.                 if (*--cp == '.')
  269.                     break;
  270.                 /*
  271.                  * All-numeric, no dot at the end.
  272.                  * Fake up a hostent as if we'd actually
  273.                  * done a lookup.
  274.                  */
  275.                 if (!inet_aton(name, &host_addr)) {
  276.                     h_errno = HOST_NOT_FOUND;
  277.                     return((struct hostent *) NULL);
  278.                 }
  279.                 host.h_name = (char *)name;
  280.                 host.h_aliases = host_aliases;
  281.                 host_aliases[0] = NULL;
  282.                 host.h_addrtype = AF_INET;
  283.                 host.h_length = sizeof(u_int32_t);
  284.                 h_addr_ptrs[0] = (char *)&host_addr;
  285.                 h_addr_ptrs[1] = (char *)0;
  286. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  287.                 host.h_addr_list = h_addr_ptrs;
  288. #else
  289.                 host.h_addr = h_addr_ptrs[0];
  290. #endif
  291.                 return (&host);
  292.             }
  293.             if (!isdigit(*cp) && *cp != '.') 
  294.                 break;
  295.         }
  296.  
  297.     if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
  298. #ifdef DEBUG
  299.         if (_res.options & RES_DEBUG)
  300.             printf("res_search failed\n");
  301. #endif
  302.         if (errno == ECONNREFUSED)
  303.             return (_gethtbyname(name));
  304.         else
  305.             return ((struct hostent *) NULL);
  306.     }
  307.     return (getanswer(&buf, n, 0));
  308. }
  309.  
  310. struct hostent *
  311. gethostbyaddr(addr, len, type)
  312.     const char *addr;
  313.     int len, type;
  314. {
  315.     int n;
  316.     querybuf buf;
  317.     register struct hostent *hp;
  318.     char qbuf[MAXDNAME];
  319.     extern struct hostent *_gethtbyaddr();
  320.     
  321.     if (type != AF_INET)
  322.         return ((struct hostent *) NULL);
  323.     (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
  324.         ((unsigned)addr[3] & 0xff),
  325.         ((unsigned)addr[2] & 0xff),
  326.         ((unsigned)addr[1] & 0xff),
  327.         ((unsigned)addr[0] & 0xff));
  328.     n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
  329.     if (n < 0) {
  330. #ifdef DEBUG
  331.         if (_res.options & RES_DEBUG)
  332.             printf("res_query failed\n");
  333. #endif
  334.         if (errno == ECONNREFUSED)
  335.             return (_gethtbyaddr(addr, len, type));
  336.         return ((struct hostent *) NULL);
  337.     }
  338.     hp = getanswer(&buf, n, 1);
  339.     if (hp == NULL)
  340.         return ((struct hostent *) NULL);
  341.     hp->h_addrtype = type;
  342.     hp->h_length = len;
  343.     h_addr_ptrs[0] = (char *)&host_addr;
  344.     h_addr_ptrs[1] = (char *)0;
  345.     host_addr = *(struct in_addr *)addr;
  346. #if BSD < 43 && !defined(h_addr)    /* new-style hostent structure */
  347.     hp->h_addr = h_addr_ptrs[0];
  348. #endif
  349.     return(hp);
  350. }
  351.  
  352. void
  353. _sethtent(f)
  354.     int f;
  355. {
  356.     if (hostf == NULL)
  357.         hostf = fopen(_PATH_HOSTS, "r" );
  358.     else
  359.         rewind(hostf);
  360.     stayopen |= f;
  361. }
  362.  
  363. void
  364. _endhtent()
  365. {
  366.     if (hostf && !stayopen) {
  367.         (void) fclose(hostf);
  368.         hostf = NULL;
  369.     }
  370. }
  371.  
  372. struct hostent *
  373. _gethtent()
  374. {
  375.     char *p;
  376.     register char *cp, **q;
  377.  
  378.     if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
  379.         return (NULL);
  380. again:
  381.     if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
  382.         return (NULL);
  383.     if (*p == '#')
  384.         goto again;
  385.     cp = strpbrk(p, "#\n");
  386.     if (cp == NULL)
  387.         goto again;
  388.     *cp = '\0';
  389.     cp = strpbrk(p, " \t");
  390.     if (cp == NULL)
  391.         goto again;
  392.     *cp++ = '\0';
  393.     /* THIS STUFF IS INTERNET SPECIFIC */
  394. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  395.     host.h_addr_list = host_addrs;
  396. #endif
  397.     host.h_addr = hostaddr;
  398.     *((u_int32_t *)host.h_addr) = inet_addr(p);
  399.     host.h_length = sizeof (u_int32_t);
  400.     host.h_addrtype = AF_INET;
  401.     while (*cp == ' ' || *cp == '\t')
  402.         cp++;
  403.     host.h_name = cp;
  404.     q = host.h_aliases = host_aliases;
  405.     cp = strpbrk(cp, " \t");
  406.     if (cp != NULL) 
  407.         *cp++ = '\0';
  408.     while (cp && *cp) {
  409.         if (*cp == ' ' || *cp == '\t') {
  410.             cp++;
  411.             continue;
  412.         }
  413.         if (q < &host_aliases[MAXALIASES - 1])
  414.             *q++ = cp;
  415.         cp = strpbrk(cp, " \t");
  416.         if (cp != NULL)
  417.             *cp++ = '\0';
  418.     }
  419.     *q = NULL;
  420.     return (&host);
  421. }
  422.  
  423. struct hostent *
  424. _gethtbyname(name)
  425.     char *name;
  426. {
  427.     register struct hostent *p;
  428.     register char **cp;
  429.     
  430.     _sethtent(0);
  431.     while (p = _gethtent()) {
  432.         if (strcasecmp(p->h_name, name) == 0)
  433.             break;
  434.         for (cp = p->h_aliases; *cp != 0; cp++)
  435.             if (strcasecmp(*cp, name) == 0)
  436.                 goto found;
  437.     }
  438. found:
  439.     _endhtent();
  440.     return (p);
  441. }
  442.  
  443. struct hostent *
  444. _gethtbyaddr(addr, len, type)
  445.     const char *addr;
  446.     int len, type;
  447. {
  448.     register struct hostent *p;
  449.  
  450.     _sethtent(0);
  451.     while (p = _gethtent())
  452.         if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
  453.             break;
  454.     _endhtent();
  455.     return (p);
  456. }
  457.  
  458. #if defined(BSD43_BSD43_NFS) || defined(sun)
  459. /* some libc's out there are bound internally to these names (UMIPS) */
  460. void
  461. ht_sethostent(stayopen)
  462.     int stayopen;
  463. {
  464.     _sethtent(stayopen);
  465. }
  466.  
  467. void
  468. ht_endhostent()
  469. {
  470.     _endhtent();
  471. }
  472.  
  473. struct hostent *
  474. ht_gethostbyname(name)
  475.     char *name;
  476. {
  477.     return _gethtbyname(name);
  478. }
  479.  
  480. struct hostent *
  481. ht_gethostbyaddr(addr, len, type)
  482.     const char *addr;
  483.     int len, type;
  484. {
  485.     return _gethtbyaddr(addr, len, type);
  486. }
  487.  
  488. struct hostent *
  489. gethostent()
  490. {
  491.     return _gethtent();
  492. }
  493.  
  494. void
  495. dns_service()
  496. {
  497.     return;
  498. }
  499.  
  500. #undef dn_skipname
  501. dn_skipname(comp_dn, eom)
  502.     const u_char *comp_dn, *eom;
  503. {
  504.     return __dn_skipname(comp_dn, eom);
  505. }
  506. #endif /*old-style libc with yp junk in it*/
  507.